package net;

import game.Game;
import game.Player;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import comm.Commands;
import comm.IllegalCommandException;

public class ClientSession extends Thread {
   
   private BufferedReader in;
   private PrintWriter out;
   private String inLine;
   private Player player;
   private Game game;
   private Commands cmd;
   private Socket socket;
   private Communications communications;

   private boolean running = true;
   
   public ClientSession(Socket socket, Game game, Communications communications) throws IOException {
      this.game = game;
      this.socket = socket;
      this.communications = communications;
      cmd = new Commands(this, game);
      out = new PrintWriter(socket.getOutputStream(), true);
      in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      dispatch("Come on now.. pick a name!");
   }
   
   /**
    * Sends a message to the client
    */
   public void dispatch(String msg) {
      out.println(msg + "\n");
   }
   
   /**
    * Sends a message to everyone except itself
    */
   public void say(String msg) {
      communications.dispatchAllUsersExcept(msg, this);
   }
   
   @Override
   public void run() {
      try {
         while (running && (inLine = in.readLine()) != null/* && !inLine.equals("")*/) {
            try {
               cmd.execute(inLine);
            } catch (IllegalCommandException e) {
               dispatch(e.getMessage());
            }
         }
      } catch (IOException e) {
         close();
      } finally {
         close();
      }
   }
   
   /**
    * Closes the clientSession
    */
   public void close() {
      System.out.println("Closing " + this + " (" + player + ").");
      running = false;
      if (player != null) {
         player.remove();
         communications.dispatchServerMsg(player + " LEFT!");
      }
      communications.removeClientSession(this);
      out.close();
      try {
         in.close();
         socket.close();
      } catch (IOException e) {
         System.out.println("Closing ClientSession failed!");
      }
   }

   public Player setPlayer(String name) {
      player = game.addPlayer(name);
      return player;
   }

   public Player getPlayer() {
      return player;
   }
   
   public Communications getCommunications() {
      return communications;
   }
}
